/**
 * 
 */
package com.xored.glance.ui.controls;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.ListenerList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

import com.xored.glance.core.ISourceListener;
import com.xored.glance.core.ITextProvider;
import com.xored.glance.core.ITextSource;
import com.xored.glance.ui.UIUtils;

/**
 * @author Yuri Strot
 * 
 */
public class ControlProvider implements ITextProvider, Listener {

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.core.ITextProvider#addSourceListener(com.xored.glance
	 * .core.ISourceListener)
	 */
	public void addSourceListener(ISourceListener listener) {
		assert listener != null;
		if (listeners.size() == 0) {
			UIUtils.getDisplay().addFilter(SWT.FocusIn, this);
		}
		listeners.add(listener);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.xored.glance.core.ITextProvider#removeSourceListener(com.xored.glance
	 * .core.ISourceListener)
	 */
	public void removeSourceListener(ISourceListener listener) {
		listeners.remove(listener);
		if (listeners.size() == 0) {
			UIUtils.getDisplay().removeFilter(SWT.FocusIn, this);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.xored.glance.core.ITextProvider#getSource()
	 */
	public ITextSource getSource() {
		final Control control = UIUtils.getDisplay().getFocusControl();
		if (control == null || control.isDisposed())
			return null;
		ITextSource source = sources.get(control);
		if (source == null) {
			if (control instanceof StyledText) {
				StyledText text = (StyledText) control;
				source = new StyledTextSource(text);
				sources.put(control, source);
				control.addDisposeListener(new DisposeListener() {

					public void widgetDisposed(DisposeEvent e) {
						sources.remove(control);
						control.removeDisposeListener(this);
					}
				});
			}
		}
		return source;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.
	 * Event)
	 */
	public void handleEvent(Event event) {
		Object[] objects = listeners.getListeners();
		for (Object object : objects) {
			ISourceListener listener = (ISourceListener) object;
			listener.sourceChanged(getSource());
		}
	}

	private Map<Control, ITextSource> sources = new HashMap<Control, ITextSource>();
	protected ListenerList listeners = new ListenerList();

}
